#ifndef __MUTEXQUEUE_H__
#define __MUTEXQUEUE_H__

/**
 * @file mutexqueue.h
 * @brief Librairie de liste chainée avec mutex.
 * @author Florian.B
 * @version 0.1
 * @date 4 avril 2012
 *
 * Librairie fournissant un gestionnaire de liste chainée avec des mutex pour pallier au problème lecteur rédacteur.
 *
 */

#include <pthread.h>
#include <signal.h>
#include "../tools/list.h"
#include "../tools/intlist.h"

/**
 *@param CONTINU est la variable de boucle des threads qui permet de leur dire de s'arrêter
 */
extern volatile sig_atomic_t CONTINUE_SERVER;

/**
 * @struct MutexQueue
 * @brief Objet MutexQueue
 *
 * MutexQueue est un petit objet qui permet de gerer une file par le biais d'une liste en gérant les accès concurrents de lecteur rédacteur.
 */
typedef struct _MutexQueue
{
  int nbElementMax; /*!< Le nombre d'élément maximum contenu dans la liste */
  List fileSocket; /*!< La file contenant les donnnées. */
  pthread_mutex_t mutexAcces; /*!< Le mutex d'ajout ou de suppression d'une entrée. */
  pthread_cond_t condVide; /*!< La condition d'attente sur une liste vide. */
}MutexQueue;

/**
 * @enum MutexQueueReturn
 * @brief Constantes de retour.
 *
 * MutexQueueReturn est une série de constatnes prédéfinie pour diverses futures fonctions de l'objet MutexQueue.
 */
typedef enum
  {
    MUTEXQUEUE_SUCCESS = 0, /*!< Succès. */
    MUTEXQUEUE_MAX = -1, /*!< File remplie. */
    MUTEXQUEUE_ERR = -2, /*!< Erreur. */
    MUTEXQUEUE_END = -3, /*!< Fin de la connexion. */
    MUTEXQUEUE_NB_RET /*!< Nombre total de constantes de retour. */
  }MutexQueueReturn;

/**
 * @fn void initializes_MutexQueue(MutexQueue *mutexQueue, const int nbElementMax)
 * @brief Fonction d'initialisation d'un mutexQueue.
 *
 * @param[in,out] mutexQueue Mutex à initialiser.
 * @param nbElementMax Le nombre d'élément maximum dans la liste.
 */
void initialize_MutexQueue(MutexQueue *mutexQueue, const int nbElementMax);

/**
 * @fn void testament_Mutex(Mutex *mutex)
 * @brief Fonction de libération d'un mutexQueue.
 *
 * @param[in,out] mutexQueue MutexQueue qui sera libérée.
 */
void testament_MutexQueue(MutexQueue *mutexQueue);

/**
 * @fn MutexQueueReturn insert_MutexQueue(MutexQueue *mutexQueue, const Element element);
 * @brief Fonction d'ajout en queue dans la liste.
 *
 * @param[in,out] mutexQueue Le MutexQueue qui prendra l'élément.
 * @param element L'élément à insérer.
 * @return MUTEX_SUCCESS pour le succès, MUTEXQUEUE_MAX si il y a trop d'élément dans la liste et MUTEXQUEUE_ERR en cas d'erreur.
 */
MutexQueueReturn insert_MutexQueue(MutexQueue *mutexQueue, const Element element);

/**
 * @fn Element getFirst_MutexQueue(MutexQueue *mutexQueue)
 * @brief Fonction qui retourne le premier élément de la liste et qui le supprime de la liste.
 *
 * @param[in,out] mutexQueue Le MutexQueue qui retourne l'élément et qui le supprime.
 * @return L'élément en tête de la liste ou NULL si la liste est vide
 */
int getFirst_MutexQueue(MutexQueue *mutexQueue);

/**
 * @fn void notifyEnd_MutexQueue(MutexQueue *mutexQueue)
 * @brief Fonction qui envoie à tous les threads qu'il faut terminer la connexion.
 *
 * @param[in,out] mutexQueue Le mutex de travail.
 */
void notifyEnd_MutexQueue(MutexQueue *mutexQueue);

#endif
